8. OAuth¶
- OAuth官网 1
- OAuth官网 2
- 一种授权机制,一种开发网络标准,主要用来颁发token
- 当前版本3.0
- 流程图如下:
- OAuth 2.0定义了authorization grant四种授权方式。
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credential
8.1. Authorization Code¶
适用于有后端的web应用
授权码通过前端传送
优点是令牌后端存储,且与资源服务器通信都在后端完成,避免令牌泄露
下图是模拟的用户访问北京图灵学院的博客平台后,利用QQ授权服务器, 整个流程发生的信息交换流程图:
下面对整个流程做一下解释:
北京图灵学院博客服务器第一次向qq授权服务器申请认证的URI,包含以下参数:
response_type:表示授权类型,必选项,此处的值固定为”code”
client_id:表示客户端的ID,必选项
redirect_uri:表示重定向URI,可选项
scope:表示申请的权限范围,可选项
state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
例如:
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
qq服务器向北京图灵学院博客服务器的URI,包含以下参数:
code:表示授权码,必选项。
- 该码的有效期应该很短,通常设为10分钟,
- 客户端只能使用该码一次,否则会被授权服务器拒绝。
- 该码与客户端ID和重定向URI,是一一对应关系。
state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。
例如:
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz
北京图灵学院博客服务器端向qq认证服务器申请令牌的HTTP请求,包含以下参数:
grant_type:表示使用的授权模式,必选项,此处的值固定为”authorization_code”。
code:表示上一步获得的授权码,必选项。
redirect_uri:表示重定向URI,必选项,且必须与上一步中的该参数值保持一致。
client_id:表示客户端ID,必选项。
client_secret:服务器密码
例如:
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
qq认证服务器向北京图灵学院博客服务器发送的HTTP回复,包含以下参数:
access_token:表示访问令牌,必选项。
token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
示例:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
8.2. implicit¶
此种方式不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了”授权码”这个步骤,因此得名
所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证
这种方式把令牌直接传给前端,是很不安全的
只能用于一些安全要求不高的场景
并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
访问的示例图如下所示
上面第一步,北京图灵学院博客服务器提供一个链接,要求用户跳转到qq授权服务器,授权用户数据给
response_type参数为token,表示要求直接返回令牌。
例如
https://b.com/oauth/authorize? response_type=token& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read
第二步,用户跳转到qq授权网站,登录后同意给予北京图灵学院博客网站授权。 这时,qq授权网站就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数, 传给北京图灵学院博客网站。
token参数就是令牌,北京图灵学院博客网站因此直接在前端拿到令牌。
令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring), 这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在”中间人攻击”的风险, 而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。
例如:
https://a.com/callback#token=ACCESS_TOKEN
8.3. 密码方式¶
用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌
这种方式需要用户给出自己的用户名/密码,风险很大
只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。
示例如图:
第一步,北京图灵学院博客网站要求用户提供qq授权网站的用户名和密码。
拿到以后,北京图灵学院博客就直接向qq授权服务器请求令牌。
grant_type参数是授权方式,这里的password表示”密码式”
username和password是qq网的用户名和密码。
例如:
https://oauth.b.com/token? grant_type=password& username=USERNAME& password=PASSWORD& client_id=CLIENT_ID
第二步
- qq授权网站验证身份通过后,直接给出令牌
- 这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,北京图灵学院博客因此拿到令牌。
8.4. 凭证模式¶
适用于没有前端的命令行应用,即在命令行下请求令牌。
这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
第一步
A 应用在命令行向 B 发出请求。
grant_type参数等于client_credentials表示采用凭证式
client_id和client_secret用来让qq认证服务器确认申请者的身份。
例如:
https://oauth.b.com/token? grant_type=client_credentials& client_id=CLIENT_ID& client_secret=CLIENT_SECRET
第二步,B 网站验证通过以后,直接返回令牌。
令牌的使用
北京图灵学院博客网站拿到令牌以后,就可以向qq网站的 API 请求数据了
每个发到 API 的请求,都必须带有令牌。
具体做法是在请求的头信息,加上一个Authorization字段,令牌就放在这个字段里面。
例如:
curl -H "Authorization: Bearer ACCESS_TOKEN" \ "https://api.b.com"
更新令牌
OAuth 2.0 允许用户自动更新令牌。
授权网站颁发令牌的时候,一次性颁发两个令牌
- 获取数据令牌
- 获取新的令牌(refresh token 字段)。
令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。
例如:
https://b.com/oauth/token? grant_type=refresh_token& client_id=CLIENT_ID& client_secret=CLIENT_SECRET& refresh_token=REFRESH_TOKEN